#include <iostream>
#include <string>
#include <curl.h>
#include "test.h"
#include <json/json.h>
#include <stdio.h>
#include <stdlib.h>
#include "mongoose/mongoose.h"
#include "utils/CUitl.h"

// 回调函数用于接收HTTP响应内容
size_t writeCallback(char* contents, size_t size, size_t nmemb, std::string* output) {
    size_t totalSize = size * nmemb;
    output->append(contents, totalSize);
    return totalSize;
}

int test_curl(char * url) {
    // 初始化libcurl
    curl_global_init(CURL_GLOBAL_DEFAULT);

    // 创建一个CURL对象
    CURL* curl = curl_easy_init();
    if(curl) {
        // 设置请求的URL
        curl_easy_setopt(curl, CURLOPT_URL, url);

        // 设置接收响应内容的回调函数和输出变量
        std::string response;
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

        // 执行HTTP请求
        CURLcode res = curl_easy_perform(curl);
        if(res != CURLE_OK) {
            std::cerr << "Failed to perform request: " << curl_easy_strerror(res) << std::endl;
        } else {
            // 请求成功，输出响应内容
            std::cout << response << std::endl;
        }

        // 清理CURL对象
        curl_easy_cleanup(curl);
    }

    // 清理libcurl
    curl_global_cleanup();
    
    return 0;
}

static const char *s_http_addr = "http://0.0.0.0:9000";    // HTTP port
static const char *s_https_addr = "https://0.0.0.0:9443";  // HTTPS port
static const char *s_root_dir = ".";

int resp(struct mg_connection *c, Json::Value js) {
    mg_http_reply(c, 200, "", js.toStyledString().c_str());
    return 0;
}

// We use the same event handler function for HTTP and HTTPS connections
// fn_data is NULL for plain HTTP, and non-NULL for HTTPS
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
    if (ev == MG_EV_HTTP_MSG) {
        struct mg_http_message *hm = (struct mg_http_message *)ev_data;
        if (mg_http_match_uri(hm, "/api/stats")) {
            // Print some statistics about currently established connections
            // mg_printf(c,
            //           "HTTP/1.1 200 OK\r\nTransfer-Encoding:
            //           chunked\r\n\r\n");
            mg_http_printf_chunk(c,
                                 "ID PROTO TYPE      LOCAL           REMOTE\n");
            for (struct mg_connection *t = c->mgr->conns; t != NULL;
                 t = t->next) {
                // mg_http_printf_chunk(
                //     c, "%-3lu %4s %s %M %M\n", t->id, t->is_udp ? "UDP" :
                //     "TCP", t->is_listening  ? "LISTENING" : t->is_accepted ?
                //     "ACCEPTED "
                //                      : "CONNECTED",
                //     mg_print_ip, &t->loc, mg_print_ip, &t->rem);
            }
            // mg_http_printf_chunk(c, "");  // Don't forget the last empty
            // chunk
        } else if (mg_http_match_uri(hm, "/heartbeat/*")) {
            Json::Value v, vr;
            v["cmd"] = "heartbeat";
            v["code"] = 0;
            v["msg"] = "ok";
            std::string res(hm->body.ptr);
            std::cout<<"res-----> "<< res.c_str() << std::endl;
            CUitl::str2json(res, vr);
            printf("vr --> %s\n", vr.toStyledString().c_str());
            v["req"] = vr["body"]["req"];
            int t = vr["body"]["time"].asInt() +8*60*60;
            std::string timestr = CUitl::timestamp2str(t);
            printf("reqest -->%s\n %s\n", timestr.c_str(),hm->body.ptr);
            printf("resp -->\n %s\n", v.toStyledString().c_str());
            resp(c, v);
        } else {
            struct mg_http_serve_opts opts = {.root_dir = s_root_dir};
            mg_http_serve_dir(c, (struct mg_http_message *)ev_data, &opts);
        }
    }
    (void)fn_data;
}

int server_f(void) {
    struct mg_mgr mgr;                            // Event manager
    mg_log_set(MG_LL_DEBUG);                      // Set log level
    mg_mgr_init(&mgr);                            // Initialise event manager
    mg_http_listen(&mgr, s_http_addr, fn, NULL);  // Create HTTP listener
    mg_http_listen(&mgr, s_https_addr, fn, (void *)1);  // HTTPS listener
    for (;;) mg_mgr_poll(&mgr, 1000);                   // Infinite event loop
    mg_mgr_free(&mgr);
    return 0;
}